/*********************************************************************
	\file :           os_sw_layers\bios\gpt\Gpt.c 
	\brief:           General purpose timer.
	\author:          Manuel Sandoval
	\version:         1.0
	\date:            Wed, 12, Feb 2014 
*********************************************************************/

/******************************* Includes**********************************/
#include "Gpt.h"

/******************************* Defines **********************************/

/******************************* Enumerations******************************/


/******************************* Structures *******************************/


/******************************* Global Variables **********************************/


/******************************* Functions ********************************/

/***************************************************************************
*
*   FUNCTION NAME: Gpt_ConfigTimer
*
***************************************************************************/
/**
* @brief Provides a single interface to configure timer channels using the appropriate parameters.
*
*
* @param[in] *ChannelConfig - See PIT_ChannelConfigType.
* @param[in] *Channel - .
*
* @return void.
*
* None.
*
***************************************************************************/
static void Gpt_ConfigTimer(const PIT_ChannelConfigType* ChannelConfig, const u8* Channel);



/***************************************************************************
*
*   FUNCTION NAME: Gpt_Init
*
***************************************************************************/
/**
* @brief Initializes the hardware timer module according to configuration set referenced by ConfigPtr.
*
*
* @param[in] *ConfigPtr - See Gpt_ConfigType.
*
* @return void.
*
* None.
*
***************************************************************************/
void Gpt_Init(const Gpt_ConfigType* ConfigPtr)
{
    
    u8 u8ChannelsToConfig = ConfigPtr->psGptDeviceConfig->psDeviceConfig->u8NumberOfPITChannels;
    
    /*!< Timer odd number 781.25 us. */

    PITCFLMT = 0;						 											/*!<  Disable PIT */
    
    PITCFLMT_PITFRZ        = 1u;													/*!< PIT counter freeze while in Freeze mode */
    
    PITMTLD0 = ConfigPtr->psGptDeviceConfig->psDeviceConfig->u8MicroSourceTimer0;		    /*!<  Microtimer 0 Load */
    
    PITMTLD1 = ConfigPtr->psGptDeviceConfig->psDeviceConfig->u8MicroSourceTimer1;			/*!<  Microtimer 1 Load */
    

    while(u8ChannelsToConfig--)
    {
      Gpt_ConfigTimer(&(ConfigPtr->psGptDeviceConfig->psDeviceConfig->psChannelConfig[u8ChannelsToConfig]),&u8ChannelsToConfig);
    }
    
    /*!<  Access to configuration data registers for interrupts */
    INT_CFADDR               = 0x70; 				/*!<  with vectors from 0xFF70 to 0xFF7E */
       
    INT_CFDATA5              = 0x06; 				/*!<  Periodic Interrupt Timer Channel 0, S12 Core handled, priority 6 */


}

 

/***************************************************************************
*
*   FUNCTION NAME: Gpt_StartTimer
*
***************************************************************************/
/**
* @brief Starts the selector timer channel with a defined timeout period.
*
*
* @param[in] Gpt_ChannelType - Numeric identifier of the GPT channel.
* @param[in] Gpt_ValueType - Timeout period (In number of ticks) after a notification shall occur.
*
* @return void.
*
* None.
*
***************************************************************************/
void Gpt_StartTimer(Gpt_ChannelType Channel, Gpt_ValueType Value)
{
    if(0 == Mcal_Pit_ChannelConfig[Channel].TimerSource) 
    {
    	/*!< Load 8-bit microtimer load register 0 into the 8-bit micro timer down-counter 0 */
        PITCFLMT_PFLMT0     = 1u;
    } else{
    	/*!< Load 8-bit microtimer load register 1 into the 8-bit micro timer down-counter 1 */
        PITCFLMT_PFLMT1     = 1u;
    
    }
    
    
    PITCE                 |= (u8)(1 << (Channel));		/*!< Channel enable */

    PITFLT   |= (u8)(1 << Channel);						/*!< Load 16-bit timer load register into the 16-bit timer down-counter */
         
     
}



/***************************************************************************
*
*   FUNCTION NAME: Gpt_StopTimer
*
***************************************************************************/
/**
* @brief Stops the selected timer channel.
*
*
* @param[in] Gpt_ChannelType - Numeric identifier of the GPT channel.
*
* @return void.
*
* None.
*
***************************************************************************/
void Gpt_StopTimer(Gpt_ChannelType Channel)
{ 
	/*!< Disabling channel */
    PITCE                 &= ~(1 << (Channel));       
}


/***************************************************************************
*
*   FUNCTION NAME: Gpt_EnableNotification
*
***************************************************************************/
/**
* @brief Enables the invocation of the configured notification function for a channel.
*
*
* @param[in] Gpt_ChannelType - Numeric identifier of the GPT channel.
*
* @return void.
*
* None.
*
***************************************************************************/
 
void Gpt_EnableNotification(Gpt_ChannelType Channel)
{
	/*!< Mask to enable PIT Interruption */
    u8 u8IntEnableMsk = (u8)(1 << Channel);
    
    /*!< Channel validator */
    
    if((Mcal_Pit_DeviceConfig[0].u8NumberOfPITChannels > Channel) && (0 <= Channel))
    {
    	/*!< Interrupt of PIT channel is enabled */
        PITINTE |= u8IntEnableMsk;
    }
    
    /*!< Enable Periodic Interrup Timer */
    PITCFLMT_PITE       = 1u;              
}


/***************************************************************************
*
*   FUNCTION NAME: Gpt_DisableNotification
*
***************************************************************************/
/**
* @brief Disables the invocation of the configured notification function for a channel.
*
*
* @param[in] Gpt_ChannelType - Numeric identifier of the GPT channel.
*
* @return void.
*
* None.
*
***************************************************************************/
void Gpt_DisableNotification(Gpt_ChannelType Channel)
{
	/*!< Mask to enable PIT Interruption */
    u8 u8IntDisableMsk = ~(1 << Channel);
    
    /*!< Validating channel */
    if((Mcal_Pit_DeviceConfig[0].u8NumberOfPITChannels > Channel) && (0 <= Channel))
    {
    	/*!< Interrupt of PIT channel is enabled */
        PITINTE &= u8IntDisableMsk;
    }               
}


/***************************************************************************
*
*   FUNCTION NAME: Gpt_ConfigTimer
*
***************************************************************************/
/**
* @brief Provides a single interface to configure timer channels using the appropriate parameters.
*
*
* @param[in] *ChannelConfig - See PIT_ChannelConfigType.
* @param[in] *Channel - .
*
* @return void.
*
* None.
*
***************************************************************************/
 
static void Gpt_ConfigTimer(const PIT_ChannelConfigType* ChannelConfig, const u8* Channel)
{
	/*!< Variable to retrieve Microtimer value */
    u16 u16MicrotimerValue;

    /*!< Select microtimer source for appropiate channel */
    if(ChannelConfig[*Channel].TimerSource == 0) 
    {
    	/*!< Select microtimer source 0 */
        PITMUX &= (~(1 << (*Channel)));
    } 
    else 
    {
    	/*!< Select microtimer source 1 */
        PITMUX |= (1 << (*Channel));
    }
    
    /*!< Interrupt of PIT channel is enabled */
    Gpt_EnableNotification(*Channel);
    
    /*!< Clear PTI interrupt flag */
    PITTF                   |= (1 << (*Channel)); 
    
    /*!< Retrieve Microtimer value */
    if(0 == ChannelConfig[*Channel].TimerSource) 
    {
    	/*!< Microtimer 0 */
        u16MicrotimerValue = PITMTLD0;                 
    } else {
    	/*!< Microtimer 1 */
        u16MicrotimerValue = PITMTLD1;          
    }
   
    /*!< Calculate PIT count down value */
    *((&PITLD0) + (sizeof(u16))*(*Channel)) = (u16)((((ChannelConfig[*Channel].TimeInMicroseconds) * (CNF_DESIRED_FREQ/2)) / ((u16MicrotimerValue + 1 ) * 1000)) - 1);
     
}


/***************************************************************************
*
*   FUNCTION NAME: Gpt_Channel0_Isr
*
***************************************************************************/
/**
* @brief PIT Channel 0 ISR --> Main CPU.
*
*
* @param[in] .
*
* @return void.
*
* None.
*
***************************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED           
 
void interrupt Gpt_Channel0_Isr(void)
{
	/*!< Verify that Real Time Interrupt caused the interrupt */
    if( PITTF_PTF0 == 1u )
    {
      if(NULL != Mcal_Gpt_Config->psGptDeviceConfig->psDeviceConfig->psChannelConfig->CallbackFunction) 
      {
    	  /*!< Executing callback */
          Mcal_Gpt_Config->psGptDeviceConfig->psDeviceConfig->psChannelConfig->CallbackFunction();
      } 
    }
    /*!< Clear the real time interrupt flag */
    PITTF_PTF0 = 1u;         
}

#pragma CODE_SEG DEFAULT



/** @} *//* End of MCU configuration Group */


/*********************************************************************
	File	: os_sw_layers\bios\gpt\Gpt.c 
*********************************************************************/
